package com.example.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationParam;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.example.entity.*;
import com.example.mapper.*;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * AI聊天服务
 */
@Service
public class AiChatService {

    @Resource
    private ChatMessageMapper chatMessageMapper;

    @Resource
    private Generation generation;
    
    @Resource
    private ChoiceMapper choiceMapper;
    
    @Resource
    private CourseMapper courseMapper;
    
    @Resource
    private ScoreMapper scoreMapper;
    
    @Resource
    private StudentMapper studentMapper;
    
    @Resource
    private TeacherMapper teacherMapper;
    
    @Resource
    private HomeworkMapper homeworkMapper;
    
    @Resource
    private AttendanceMapper attendanceMapper;
    
    @Resource
    private ApplyMapper applyMapper;
    
    // 注入API密钥
    @org.springframework.beans.factory.annotation.Value("${spring.ai.dashscope.api-key}")
    private String apiKey;

    /**
     * 发送消息并获取AI回复
     */
    public String chat(String userMessage) {
        // 每次调用前都设置API密钥，确保DashScope SDK能找到
        System.setProperty("dashscope.api.key", apiKey);
        
        Account currentUser = TokenUtils.getCurrentUser();
        
        // 构建系统提示词，根据用户角色定制
        String systemPrompt = buildSystemPrompt(currentUser.getRole());
        
        // 获取最近的聊天历史（最多5条）
        List<ChatMessage> history = chatMessageMapper.selectByUserIdWithLimit(currentUser.getId(), 5);
        
        // 构建消息列表（包含历史对话）
        List<Message> messages = new ArrayList<>();
        
        // 添加系统提示词
        messages.add(Message.builder()
                .role(Role.SYSTEM.getValue())
                .content(systemPrompt)
                .build());
        
        // 添加历史对话（逆序遍历，保持时间顺序）
        for (int i = history.size() - 1; i >= 0; i--) {
            ChatMessage msg = history.get(i);
            messages.add(Message.builder()
                    .role(Role.USER.getValue())
                    .content(msg.getUserMessage())
                    .build());
            messages.add(Message.builder()
                    .role(Role.ASSISTANT.getValue())
                    .content(msg.getAiResponse())
                    .build());
        }
        
        // 添加当前用户消息
        messages.add(Message.builder()
                .role(Role.USER.getValue())
                .content(userMessage)
                .build());
        
        // 调用通义千问获取回复
        String aiResponse;
        try {
            GenerationParam param = GenerationParam.builder()
                    .apiKey(apiKey)  // 🔑 直接在参数中设置API密钥（最可靠的方式）
                    .model("qwen-plus")  // 使用qwen-plus模型
                    .messages(messages)
                    .temperature(Float.valueOf("0.7"))
                    .topP(Double.valueOf("0.8"))
                    .resultFormat(GenerationParam.ResultFormat.MESSAGE)
                    .build();
            
            GenerationResult result = generation.call(param);
            aiResponse = result.getOutput().getChoices().get(0).getMessage().getContent();
            
        } catch (ApiException | NoApiKeyException | InputRequiredException e) {
            // 处理异常，返回友好的错误提示
            aiResponse = "抱歉，AI服务暂时不可用，请稍后再试。错误信息：" + e.getMessage();
            e.printStackTrace();
        }
        
        // 保存聊天记录到数据库
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setUserId(currentUser.getId());
        chatMessage.setUsername(currentUser.getUsername());
        chatMessage.setRole(currentUser.getRole());
        chatMessage.setUserMessage(userMessage);
        chatMessage.setAiResponse(aiResponse);
        chatMessage.setCreateTime(DateUtil.now());
        chatMessageMapper.insert(chatMessage);
        
        return aiResponse;
    }

    /**
     * 根据用户角色构建系统提示词（包含真实数据上下文）
     */
    private String buildSystemPrompt(String role) {
        Account currentUser = TokenUtils.getCurrentUser();
        
        String basePrompt = """
            你是一个高校教务管理系统的智能助手。你需要帮助用户解答关于教务系统的问题。
            
            系统功能包括：
            1. 信息公告：教务通知、考试安排、教室安排
            2. 行政管理：学院信息、专业信息、班级信息
            3. 教学管理：课程信息、选课、课表、成绩、评教
            4. 教务管理：请假申请、作业提交、考勤信息
            5. 用户管理：管理员、教师、学生信息
            
            请用友好、专业的语气回答问题。当用户询问具体数据时（如课表、成绩等），请基于下方提供的真实数据来回答。
            回答时请使用清晰的格式，适当使用换行和分点说明。
            """;
        
        // 根据角色获取并添加真实数据上下文
        String dataContext = switch (role) {
            case "STUDENT" -> buildStudentDataContext(currentUser.getId());
            case "TEACHER" -> buildTeacherDataContext(currentUser.getId());
            case "ADMIN" -> buildAdminDataContext();
            default -> "";
        };
        
        String rolePrompt = switch (role) {
            case "STUDENT" -> """
                
                当前用户是学生，你需要重点帮助：
                - 如何选课和查看课表
                - 如何查看成绩和考试安排
                - 如何提交作业和请假申请
                - 如何进行课程评教
                - 如何查看考勤情况
                """;
            case "TEACHER" -> """
                
                当前用户是教师，你需要重点帮助：
                - 如何管理课程信息
                - 如何录入学生成绩
                - 如何管理作业和考勤
                - 如何查看学生评教
                - 如何发布课程通知
                """;
            case "ADMIN" -> """
                
                当前用户是管理员，你需要重点帮助：
                - 如何管理学院、专业、班级信息
                - 如何管理用户（学生、教师）
                - 如何发布教务通知和考试安排
                - 如何管理教室资源
                - 如何进行系统配置
                """;
            default -> "";
        };
        
        return basePrompt + rolePrompt + dataContext;
    }
    
    /**
     * 构建学生数据上下文
     */
    private String buildStudentDataContext(Integer studentId) {
        StringBuilder context = new StringBuilder("\n\n=== 当前用户的真实数据 ===\n");
        
        try {
            // 获取学生基本信息
            Student student = studentMapper.selectById(studentId);
            if (student != null) {
                context.append("\n【学生基本信息】\n");
                context.append("姓名：").append(student.getName()).append("\n");
                context.append("学院：").append(student.getCollegeName()).append("\n");
                context.append("专业：").append(student.getSpecialityName()).append("\n");
                context.append("班级：").append(student.getClassName()).append("\n");
                context.append("已获学分：").append(student.getScore()).append("\n");
            }
            
            // 获取选课和课表信息
            List<Choice> choiceList = choiceMapper.selectByStudentId(studentId);
            if (!choiceList.isEmpty()) {
                context.append("\n【本学期课表】\n");
                for (Choice choice : choiceList) {
                    Course course = courseMapper.selectById(choice.getCourseId());
                    if (course != null) {
                        context.append("- ").append(course.getName())
                              .append("（").append(course.getType()).append("）\n");
                        context.append("  授课教师：").append(course.getTeacherName()).append("\n");
                        context.append("  上课时间：").append(course.getWeek())
                              .append(" ").append(course.getSegment()).append("\n");
                        context.append("  上课教室：").append(course.getRoom()).append("\n");
                        context.append("  学分：").append(course.getScore()).append("\n");
                        context.append("  课程状态：").append(course.getStatus()).append("\n");
                    }
                }
            } else {
                context.append("\n【本学期课表】\n暂无选课记录\n");
            }
            
            // 获取成绩信息
            Score scoreQuery = new Score();
            scoreQuery.setStudentId(studentId);
            List<Score> scoreList = scoreMapper.selectAll(scoreQuery);
            if (!scoreList.isEmpty()) {
                context.append("\n【成绩信息】\n");
                for (Score score : scoreList) {
                    context.append("- ").append(score.getCourseName()).append("\n");
                    context.append("  平时分：").append(score.getOrdinaryScore())
                          .append("，考试分：").append(score.getExamScore())
                          .append("，总成绩：").append(score.getScore()).append("\n");
                }
            } else {
                context.append("\n【成绩信息】\n暂无成绩记录\n");
            }
            
            // 获取作业信息
            Homework homeworkQuery = new Homework();
            homeworkQuery.setStudentId(studentId);
            List<Homework> homeworkList = homeworkMapper.selectAll(homeworkQuery);
            if (!homeworkList.isEmpty()) {
                context.append("\n【作业信息】\n");
                for (Homework homework : homeworkList) {
                    context.append("- ").append(homework.getContent()).append("\n");
                    context.append("  课程：").append(homework.getCourseName()).append("\n");
                    if (homework.getScore() != null) {
                        context.append("  得分：").append(homework.getScore()).append("\n");
                        if (homework.getDescr() != null) {
                            context.append("  评语：").append(homework.getDescr()).append("\n");
                        }
                    } else {
                        context.append("  状态：待批改\n");
                    }
                }
            } else {
                context.append("\n【作业信息】\n暂无作业记录\n");
            }
            
            // 获取考勤信息
            Attendance attendanceQuery = new Attendance();
            attendanceQuery.setStudentId(studentId);
            List<Attendance> attendanceList = attendanceMapper.selectAll(attendanceQuery);
            if (!attendanceList.isEmpty()) {
                context.append("\n【考勤信息】\n");
                for (Attendance attendance : attendanceList) {
                    context.append("- ").append(attendance.getCourseName())
                          .append(" (").append(attendance.getTime()).append("): ")
                          .append(attendance.getStatus()).append("\n");
                }
            } else {
                context.append("\n【考勤信息】\n暂无考勤记录\n");
            }
            
            // 获取请假信息
            Apply applyQuery = new Apply();
            applyQuery.setStudentId(studentId);
            List<Apply> applyList = applyMapper.selectAll(applyQuery);
            if (!applyList.isEmpty()) {
                context.append("\n【请假信息】\n");
                for (Apply apply : applyList) {
                    context.append("- 请假时间：").append(apply.getTime())
                          .append("，天数：").append(apply.getDay()).append("天\n");
                    context.append("  请假理由：").append(apply.getContent()).append("\n");
                    context.append("  审核状态：").append(apply.getStatus()).append("\n");
                    if (apply.getDescr() != null) {
                        context.append("  审核说明：").append(apply.getDescr()).append("\n");
                    }
                }
            } else {
                context.append("\n【请假信息】\n暂无请假记录\n");
            }
            
        } catch (Exception e) {
            context.append("\n数据加载失败：").append(e.getMessage()).append("\n");
        }
        
        context.append("\n=== 数据上下文结束 ===\n");
        return context.toString();
    }
    
    /**
     * 构建教师数据上下文
     */
    private String buildTeacherDataContext(Integer teacherId) {
        StringBuilder context = new StringBuilder("\n\n=== 当前用户的真实数据 ===\n");
        
        try {
            // 获取教师授课信息
            Course courseQuery = new Course();
            courseQuery.setTeacherId(teacherId);
            List<Course> courseList = courseMapper.selectAll(courseQuery);
            
            if (!courseList.isEmpty()) {
                context.append("\n【授课信息】\n");
                for (Course course : courseList) {
                    context.append("- ").append(course.getName())
                          .append("（").append(course.getType()).append("）\n");
                    context.append("  上课时间：").append(course.getWeek())
                          .append(" ").append(course.getSegment()).append("\n");
                    context.append("  上课教室：").append(course.getRoom()).append("\n");
                    context.append("  学分：").append(course.getScore())
                          .append("，容纳人数：").append(course.getNum()).append("\n");
                    context.append("  课程状态：").append(course.getStatus()).append("\n");
                    
                    // 获取选课人数
                    List<Choice> choiceList = choiceMapper.selectByCourseId(course.getId());
                    context.append("  已选人数：").append(choiceList.size()).append("\n");
                }
            } else {
                context.append("\n【授课信息】\n暂无授课安排\n");
            }
            
            // 获取作业批改信息
            Homework homeworkQuery = new Homework();
            homeworkQuery.setTeacherId(teacherId);
            List<Homework> homeworkList = homeworkMapper.selectAll(homeworkQuery);
            if (!homeworkList.isEmpty()) {
                context.append("\n【作业管理】\n");
                long pendingCount = homeworkList.stream()
                    .filter(h -> h.getScore() == null)
                    .count();
                long gradedCount = homeworkList.stream()
                    .filter(h -> h.getScore() != null)
                    .count();
                context.append("待批改作业：").append(pendingCount).append(" 份\n");
                context.append("已批改作业：").append(gradedCount).append(" 份\n");
            }
            
        } catch (Exception e) {
            context.append("\n数据加载失败：").append(e.getMessage()).append("\n");
        }
        
        context.append("\n=== 数据上下文结束 ===\n");
        return context.toString();
    }
    
    /**
     * 构建管理员数据上下文
     */
    private String buildAdminDataContext() {
        StringBuilder context = new StringBuilder("\n\n=== 系统数据概览 ===\n");
        
        try {
            // 统计基本信息
            List<Student> students = studentMapper.selectAll(new Student());
            List<Course> courses = courseMapper.selectAll(new Course());
            
            context.append("\n【系统统计】\n");
            context.append("学生总数：").append(students.size()).append("\n");
            context.append("课程总数：").append(courses.size()).append("\n");
            
        } catch (Exception e) {
            context.append("\n数据加载失败：").append(e.getMessage()).append("\n");
        }
        
        context.append("\n=== 数据上下文结束 ===\n");
        return context.toString();
    }

    /**
     * 获取聊天历史
     */
    public List<ChatMessage> getChatHistory(Integer userId, Integer limit) {
        if (limit == null) {
            limit = 20;
        }
        List<ChatMessage> messages = chatMessageMapper.selectByUserIdWithLimit(userId, limit);
        // 反转列表，使其按时间正序排列
        List<ChatMessage> result = new ArrayList<>(messages);
        java.util.Collections.reverse(result);
        return result;
    }

    /**
     * 清空聊天历史
     */
    public void clearHistory(Integer userId) {
        ChatMessage query = new ChatMessage();
        query.setUserId(userId);
        List<ChatMessage> messages = chatMessageMapper.selectAll(query);
        messages.forEach(msg -> chatMessageMapper.deleteById(msg.getId()));
    }

    /**
     * 新增
     */
    public void add(ChatMessage chatMessage) {
        chatMessage.setCreateTime(DateUtil.now());
        chatMessageMapper.insert(chatMessage);
    }

    /**
     * 删除
     */
    public void deleteById(Integer id) {
        chatMessageMapper.deleteById(id);
    }

    /**
     * 批量删除
     */
    public void deleteBatch(List<Integer> ids) {
        ids.forEach(chatMessageMapper::deleteById);
    }

    /**
     * 修改
     */
    public void updateById(ChatMessage chatMessage) {
        chatMessageMapper.updateById(chatMessage);
    }

    /**
     * 根据ID查询
     */
    public ChatMessage selectById(Integer id) {
        return chatMessageMapper.selectById(id);
    }

    /**
     * 查询所有
     */
    public List<ChatMessage> selectAll(ChatMessage chatMessage) {
        return chatMessageMapper.selectAll(chatMessage);
    }

    /**
     * 分页查询
     */
    public PageInfo<ChatMessage> selectPage(ChatMessage chatMessage, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<ChatMessage> list = chatMessageMapper.selectAll(chatMessage);
        return PageInfo.of(list);
    }
}
